﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.ExceptionManagement;

namespace Kiiro.DataAccess
{
    public class AttachmentDA
    {
        #region Singleton

        private AttachmentDA ( )
        {
        }

        private static AttachmentDA instance = null;
        private static readonly object threadLock = new object ( );

        public static AttachmentDA Instance
        {
            get
            {
                lock ( threadLock )
                {
                    if ( instance == null )
                    {
                        instance = new AttachmentDA ( );
                    }
                }
                return instance;
            }
        }

        #endregion

        public void Save ( BaseEntity entity, Guid siteCollectionId, string serverRelativeUrl )
        {
            SPList list = null;

            using ( SPWeb web = SPHelpers.GetSystemWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                try
                {
                    if ( entity is Work )
                    {
                        list = web.Lists [ "Work" ];
                    }
                    else if ( entity is Discussion || entity is Comment )
                    {
                        list = web.Lists [ "Discussions" ];
                    }

                    if ( list != null )
                    {
                        SPListItem listItem = list.Folders.GetItemById ( entity.Id );
                        if ( listItem != null && listItem.Folder != null )
                        {
                            web.AllowUnsafeUpdates = true;
                            foreach ( Attachment attachment in entity.AttachmentList )
                            {
                                switch ( attachment.EditType )
                                {
                                    case EditType.Created:
                                        if ( attachment.Bytes != null && attachment.Bytes.Length > 0 )
                                            listItem.Folder.Files.Add ( attachment.FileName, attachment.Bytes, true );
                                        break;
                                    case EditType.Deleted:
                                        listItem.Folder.Files.Delete ( attachment.FileName );
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }
                    }
                }
                catch ( Exception ex )
                {
                    ExceptionManager.HandleException ( ex, true );
                }
                finally
                {
                    if ( web != null )
                    {
                        web.AllowUnsafeUpdates = false;
                    }
                }
            }
        }

        public int GetAttachmentCount(string listName, Guid siteCollectionId, string serverRelativeUrl)
        {
            int documentAttachmentCount = 0;

            try
            {
                using (SPWeb web = SPHelpers.GetWeb(siteCollectionId, serverRelativeUrl))
                {
                    SPList list = web.Lists[listName];

                    StringBuilder queryText = new StringBuilder();
                    queryText.Append("<Where>");
                    queryText.Append("  <IsNotNull>");
                    queryText.Append("    <FieldRef Name='" + Constants.BaseEntityFieldNames.ItemId + "' />");
                    queryText.Append("  </IsNotNull>");
                    queryText.Append("</Where>");

                    SPQuery query = new SPQuery();
                    query.Query = queryText.ToString();

                    SPListItemCollection items = list.GetItems(query);

                    if (items.Count > 0)
                    {
                        foreach (SPListItem item in items)
                        {
                            documentAttachmentCount += item.Folder.Files.Count;

                            if(listName == Constants.SPListNames.Discussions)
                                foreach (SPFolder comment in item.Folder.SubFolders)
                                    documentAttachmentCount += comment.Files.Count;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.HandleException(ex, true);
            }

            return documentAttachmentCount;
        }

        public List<Attachment> GetAttachments(string listName, Guid siteCollectionId, string serverRelativeUrl)
        {
            List<Attachment> attachments = null;

            try
            {
                using (SPWeb web = SPHelpers.GetWeb(siteCollectionId, serverRelativeUrl))
                {
                    SPList list = web.Lists[listName];

                    StringBuilder queryText = new StringBuilder();
                    queryText.Append("<Where>");
                    queryText.Append("  <IsNotNull>");
                    queryText.Append("    <FieldRef Name='" + Constants.BaseEntityFieldNames.ItemId + "' />");
                    queryText.Append("  </IsNotNull>");
                    queryText.Append("</Where>");

                    SPQuery query = new SPQuery();
                    query.Query = queryText.ToString();

                    SPListItemCollection items = list.GetItems(query);

                    if (items.Count > 0)
                    {
                        attachments = new List<Attachment>();
                        foreach (SPListItem item in items)
                        {
                            Discussion disc = null;
                            Work work = null;

                            if (listName == Constants.SPListNames.Discussions)
                                disc = SPDataHelpers.MakeDiscussion(item);
                            else
                                work = SPDataHelpers.MakeWork(item);

                            foreach (SPFile attachment in item.Folder.Files)
                            {
                                Attachment a = SPDataHelpers.MakeAttachment(attachment);
                                if (listName == Constants.SPListNames.Discussions)
                                {
                                    a.Title = disc.Title;
                                    a.Id = disc.Id;
                                    a.Description = "Discussion";
                                    a.CreatedBy = disc.CreatedBy;
                                    a.CreatedDate = attachment.TimeCreated.ToLocalTime();
                                    attachments.Add(a);
                                }
                                else
                                {
                                    a.Title = work.Title;
                                    a.Id = work.Id;
                                    a.Description = work.WorkItemType.ToString();
                                    a.CreatedBy = work.CreatedBy;
                                    a.CreatedDate = attachment.TimeCreated.ToLocalTime();
                                    attachments.Add(a);
                                }
                            }

                            if (listName == Constants.SPListNames.Discussions)
                            {
                                foreach (SPFolder comment in item.Folder.SubFolders)
                                {
                                    Comment com = SPDataHelpers.MakeComment(comment.Item);
                                    foreach (SPFile attachment in comment.Files)
                                    {
                                        Attachment a = SPDataHelpers.MakeAttachment(attachment);
                                        a.Title = disc.Title;
                                        a.Id = disc.Id;
                                        a.Description = "Discussion";
                                        a.CreatedBy = com.CreatedBy;
                                        a.CreatedDate = attachment.TimeCreated.ToLocalTime();
                                        attachments.Add(a);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionManager.HandleException(ex, true);
            }

            return attachments;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.DataAccess/AttachmentDA.cs $
 * 
 * 8     12/02/09 12:29p Stefanf
 * 
 * 7     26/10/09 4:38p Camerons
 * 
 * 6     10/26/09 12:28p Adamw
 * Case 295, elevated Save method to use system site
 * 
 * 5     30/09/09 9:15a Shafia
 * 
 * 4     17/08/09 10:41a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/